package com.yourcompany.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yourcompany.api.dto.CreditPayDTO;
import com.yourcompany.api.dto.OrderCreateDTO;
import com.yourcompany.api.dto.OrderPayDTO;
import com.yourcompany.api.entity.Order;
import com.yourcompany.api.mapper.OrderMapper;
import com.yourcompany.api.service.CreditPayService;
import com.yourcompany.api.service.OrderService;
import com.yourcompany.api.strategy.PaymentStrategy;
import com.yourcompany.common.enums.OrderStatusEnum;
import com.yourcompany.common.enums.PayMethodEnum;
import com.yourcompany.common.exception.BusinessException;
import com.yourcompany.service.factory.PaymentStrategyFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    
    @Autowired
    private CreditPayService creditPayService;
    
    @Autowired
    private PaymentStrategyFactory paymentStrategyFactory;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String payOrderWithCredit(CreditPayDTO creditPayDTO) {
        // 获取订单
        Order order = getById(creditPayDTO.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        // 检查订单状态
        if (order.getStatus() != OrderStatusEnum.UNPAID.getCode()) {
            throw new BusinessException("订单状态不正确");
        }
        
        // 检查订单金额
        if (order.getAmount().compareTo(creditPayDTO.getAmount()) != 0) {
            throw new BusinessException("支付金额不正确");
        }
        
        // 使用先充后付支付
        String result = creditPayService.pay(creditPayDTO);
        
        // 更新订单状态
        order.setStatus(OrderStatusEnum.PAID.getCode());
        order.setPayMethod(PayMethodEnum.CREDIT.getCode());
        order.setPayTime(LocalDateTime.now());
        updateById(order);
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order createOrder(OrderCreateDTO createDTO) {
        // 创建订单
        Order order = new Order();
        order.setUserId(createDTO.getUserId());
        order.setOrderNo(generateOrderNo());
        order.setOrderType(createDTO.getOrderType());
        order.setBusinessId(createDTO.getBusinessId());
        order.setAmount(createDTO.getAmount());
        order.setStatus(OrderStatusEnum.UNPAID.getCode());
        order.setRemark(createDTO.getRemark());
        
        save(order);
        return order;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(Long orderId) {
        Order order = getById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (order.getStatus() != OrderStatusEnum.UNPAID.getCode()) {
            throw new BusinessException("订单状态不正确");
        }
        
        order.setStatus(OrderStatusEnum.CANCELLED.getCode());
        updateById(order);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String payOrder(OrderPayDTO payDTO) {
        // 获取订单
        Order order = getById(payDTO.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        // 检查订单状态
        if (order.getStatus() != OrderStatusEnum.UNPAID.getCode()) {
            throw new BusinessException("订单状态不正确");
        }
        
        // 检查订单金额
        if (order.getAmount().compareTo(payDTO.getAmount()) != 0) {
            throw new BusinessException("支付金额不正确");
        }
        
        // 获取支付策略
        PaymentStrategy strategy = paymentStrategyFactory.getStrategy(payDTO.getPayMethod());
        
        // 调用支付接口
        String result = String.valueOf(strategy.pay(order.getOrderNo(), String.valueOf(payDTO.getAmount())));
        
        // 更新订单状态
        order.setStatus(OrderStatusEnum.PAID.getCode());
        order.setPayMethod(payDTO.getPayMethod());
        order.setPayTime(LocalDateTime.now());
        updateById(order);
        
        return result;
    }
    
    private String generateOrderNo() {
        return "OR" + System.currentTimeMillis();
    }
} 